//
// Point.cpp for  in /home/herpec_j/Dropbox/Projets/raytracer-2016/Sources/Maths/
//
// Made by Jonathan
// Login   <ledey_l@epitech.net>
//
// Started on  Sun Sep 22 13:23:16 2013 Jonathan
// Last update Sun Sep 22 16:27:21 2013 Jonathan
//

#include		"Maths/Point.hpp"
#include		"Maths/Vector.hpp"
#include		"Maths/Matrix.hpp"

namespace		Maths
{
  Point::Point(void) : mX(0.0f), mY(0.0f), mZ(0.0f)
  {
    return;
  }

  Point::Point(long double rValue) : mX(rValue), mY(rValue), mZ(rValue)
  {
    return;
  }

  Point::Point(long double rX, long double rY, long double rZ) : mX(rX), mY(rY), mZ(rZ)
  {
    return;
  }

  Point::Point(Point const &rOther) : mX(rOther.mX), mY(rOther.mY), mZ(rOther.mZ)
  {
    return;
  }

  Point			&Point::operator=(Point const &rOther)
  {
    if (this != &rOther)
      {
	mX = rOther.mX;
	mY = rOther.mY;
	mZ = rOther.mZ;
      }
    return (*this);
  }

  Point			Point::operator-(void) const
  {
    return (Point(-mX, -mY, -mZ));
  }

  Vector		Point::operator-(Point const &rOther) const
  {
    return (Vector(mX - rOther.mX, mY - rOther.mY, mZ - rOther.mZ));
  }

  Point			Point::operator-(Vector const &rVector) const
  {
    return (Point(mX - rVector[0], mY - rVector[1], mZ - rVector[2]));
  }

  Point			Point::operator+(Vector const &rVector) const
  {
    return (Point(mX + rVector[0], mY + rVector[1], mZ + rVector[2]));
  }

  Point			Point::operator*(long double rValue) const
  {
    return (Point(mX * rValue, mY * rValue, mZ * rValue));
  }

  long double		Point::operator[](int rIndex) const
  {
    switch (rIndex)
      {
      case 0:
	return (mX);
	break;
      case 1:
	return (mY);
	break;
      case 2:
	return (mZ);
	break;
      default:
	return (0.0f);
	break;
      }
  }

  long double		Point::Distance(Point const &rOther) const
  {
    long double		x = mX - rOther.mX;
    long double		y = mY - rOther.mY;
    long double		z = mZ - rOther.mZ;

    return (sqrt(x * x + y * y + z * z));
  }

  long double		Point::Distance_Squared(Point const &rOther) const
  {
    long double		x = mX - rOther.mX;
    long double		y = mY - rOther.mY;
    long double		z = mZ - rOther.mZ;

    return (x * x + y * y + z * z);
  }

  Point::~Point(void)
  {
    return;
  }

  Point			operator*(Matrix const &rMatrix, Point const &rPoint)
  {
    long double		**matrix = rMatrix.GetMatrix();
    long double		x = rPoint[0];
    long double		y = rPoint[1];
    long double		z = rPoint[2];

    return (Point(matrix[0][0] * x + matrix[0][1] * y + matrix[0][2] * z + matrix[0][3],
		  matrix[1][0] * x + matrix[1][1] * y + matrix[1][2] * z + matrix[1][3],
		  matrix[2][0] * x + matrix[2][1] * y + matrix[2][2] * z + matrix[2][3]));
  }
};
